package com.gitee.wsl.flow.state

import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asSharedFlow

interface IStateSourceWithSharedFlow<STATE> : IStateSource<STATE> {

    /**
     * Provides a [flow][StateFlow] of [states][State]
     *
     * @return a [flow][StateFlow] of [states][State]
     */
    fun observeAllStates(): SharedFlow<STATE>
}


internal class StateSourceSharedFlowDecorator<STATE>(
    private val stateSource: IStateSource<STATE>,
) : IStateSourceWithSharedFlow<STATE> {

    private val sharedFlow = MutableSharedFlow<STATE>(replay = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST)

    init {
        sharedFlow.tryEmit(stateSource.getCurrentState())
    }

    override fun observeAllStates(): SharedFlow<STATE> {
        return sharedFlow.asSharedFlow()
    }

    override fun observeState(): StateFlow<STATE> {
        return stateSource.observeState()
    }

    override fun getCurrentState(): STATE {
        return stateSource.getCurrentState()
    }

    override fun updateState(newState: STATE) {
        stateSource.updateState(newState)
        sharedFlow.tryEmit(newState)
    }
}